package swym.client;

import java.io.*;
import java.util.*;
import com.den_4.inotify_java.*;

public class WatchHelper
{
	private final int DELETE = 0,CLOSE = 1,MODIFY = 2,CREATE = 3,MOVE_FROM = 4,MOVE_TO = 5;
	
	private ArrayList<WatchHelperListener> listeners;
	private File directory;

	public WatchHelper(File dir)
	{
		directory = dir;
		listeners = new ArrayList<WatchHelperListener>();

		try
		{
        		Inotify i = new Inotify();
		        i.addInotifyEventListener(new InotifyEventListener(){
		                public void filesystemEventOccurred(InotifyEvent e)
				{
					if(e.isFileModification())
						fireEvent(MODIFY,e.getName());
					else if(e.isCloseWritableFile())
						fireEvent(CLOSE,e.getName());
					else if(e.isCreateFile() )
						fireEvent(CREATE,e.getName());
					else if(e.isDeleteFile())
						fireEvent(DELETE,e.getName());
					else if(e.isMoveFileFrom())
						fireEvent(MOVE_FROM,e.getName());
					else if(e.isMoveFileTo())
						fireEvent(MOVE_TO,e.getName());
					
				}
		
		                public void queueFull(EventQueueFull e) {
        	            		System.out.println("inotify event queue: " + e.getSource() + " is full!");}});
            
		        i.addWatch(dir.getAbsolutePath(), Constants.IN_ALL_EVENTS);
        	}
		catch (UnsatisfiedLinkError e)
		{
	        	System.err.println(dir.getAbsolutePath() + ": unsatisfied link error");
 	       	}
		catch (UserLimitException e)
		{
            		System.err.println(dir.getAbsolutePath() + ": user limit exception");
		}
		catch (SystemLimitException e)
		{
            		System.err.println(dir.getAbsolutePath() + ": system limit exception");
	        }
		catch (InsufficientKernelMemoryException e)
		{
            		System.err.println(dir.getAbsolutePath() + ": insufficient kernel memory exception");
        	}		
	}

	private void fireEvent(int type, String fileName)
	{
		
		File f;
		
		if(fileName != null)
			f  = new File(directory.getAbsolutePath() + "/" + fileName);
		else
			f = directory;

		switch(type)
		{
			case CREATE:
				for(WatchHelperListener l : listeners)
					l.fileCreated(f);
				break;
			case MODIFY:
				for(WatchHelperListener l : listeners)
					l.fileModified(f);
				break;
			case DELETE:
				for(WatchHelperListener l : listeners)
					l.fileDeleted(f);
				break;
			case CLOSE:
				for(WatchHelperListener l : listeners)
					l.fileClosed(f);
				break;
			case MOVE_FROM:
				for(WatchHelperListener l : listeners)
					l.fileDeleted(f);
				break;
			case MOVE_TO:
				for(WatchHelperListener l : listeners)
					l.fileCreated(f);
				break;
			default:break;

		}
	}

	public void addWatchHelperListener(WatchHelperListener l)
	{
		listeners.add(l);
	}

	public void removeWatchHelperListener(WatchHelperListener l)
	{
		listeners.remove(l);
	}
}
